package Grantsfire::Controller::Feed;

use strict;
use warnings;

use XML::Feed;
use XML::Feed::Entry;
use XML::Feed::Content;
use DateTime;
use HTML::Entities;

use base 'Catalyst::Controller';

sub add : Local {
    my ( $self, $c ) = @_;

    eval {
        $c->check_params([
            url => [qw(NOT_BLANK HTTP_URL)],
            org => [qw(NOT_BLANK)],
            ]);
        die "Invalid organization\n" unless $c->model('GF::Org')->find($c->req->params->{org});
        die "A feed with this URL has already been entered\n" if $c->model('GF::Feed')->search({url=>$c->req->params->{url}})->first;
        my $feed = $c->model('GF::Feed')->create({
                url => $c->req->params->{url},
                org => $c->req->params->{org},
                user => $c->req->params->{user},
            });
        Grantsfire::Controller::Async::scan_feed($c, $feed);
    };
    if ($@) {
        $c->error($@);
    }

    my @msgs = ('Feed added.');

    # in case of failed geocoder lookups, pass notification through message
    my $geocode_failures = $c->stash->{geocode_failures};
    if ($geocode_failures && scalar(keys %$geocode_failures)) {
        push @msgs,"Could not geocode the following:";
        
        while (my ($loc, $count) = each %$geocode_failures) {
            my $msg = $loc;
            $loc .= " ($count vcards)" if $count > 1;
            push @msgs, " - " . $msg;
        }
    }

    $c->redirect_success(success => \@msgs);
}

sub remove : Regex("^feed/remove$") {   #"
    my ( $self, $c, $feed_id) = @_;
    eval {
        my $feed = $c->model('GF::Feed')->find($feed_id);
        $feed->delete;
    };
    if ($@) {
        $c->error($@);
    }
    $c->redirect_success('Feed deleted.');
}

sub default : Private {
    my ( $self, $c ) = @_;

    my $rs = $c->model('GF::Entry')->search(undef, {
    	order_by => 'modified DESC',
		rows => 100,
	})->page(1);

	$c->stash->{feed_grants} = [$rs->all];
	my $feed = $c->forward('generate');
	
    $c->res->content_type('application/atom+xml');
    $c->res->body($feed->as_xml);
}

sub generate : Private {
	my ($self, $c) = @_;
	
	my $feed_grants = $c->stash->{feed_grants} || [];
	my $feed_dest_uri = $c->stash->{feed_dest_uri} || $c->uri_for('/');

	my $feed = XML::Feed->new;
	
    $feed->title('Grantsfire');
    $feed->link($feed_dest_uri);
    $feed->tagline('A new way to share grants knowledge');
    $feed->description('Recent grants from Grantsfire');
    $feed->author('Grantsfire');
    $feed->generator('XML::Feed ' . $XML::Feed::VERSION);

    foreach my $grant (@$feed_grants) {
        my $entry = XML::Feed::Entry->new();
        $entry->title($grant->title);
        $entry->link($c->uri_for('/grant/' . $grant->id));
        $entry->content(XML::Feed::Content->new({body => encode_entities($grant->description), type => 'text/html'}));
        $entry->summary(XML::Feed::Content->new({body => encode_entities($grant->description), type => 'text/html'}));
        #$entry->category($grant->category || $grant->program_focus);
        $entry->author($grant->grantor->org);
        $entry->id($c->uri_for('/grant/' . $grant->id));
        $entry->issued($grant->created);
        $entry->modified($grant->modified);
        $feed->add_entry($entry);
    }

    $feed->modified(DateTime->now);
	return $feed;
}

sub validate_default : Regex("^feed/validate/?$") {
  shift->validate(@_);
}

sub validate : Regex("^feed/validate/(.+)$") {
  my ($self, $c) = @_;
  my $url = $c->req->captures->[0];
  $url = "" if $url == 1;
  
  my $validator = eval {Grantsfire::Schema::Feed->ValidateFeed($url)};  

  # collect response
  # format into pretty page with a template
  #   convert data to JSON
  #   use jQuery to make it sexy
  #   polish with photoshoped graphics, shadows, etc

  $c->stash->{template} = 'feed/validate.tt';

  $c->stash->{validator} = $validator;
  $c->stash->{error}     = $@;
  $c->stash->{url}       = $url;
  binmode STDOUT, ':utf8';
}

1;
